#ifndef __M_DB_H__
#define __M_DB_H__

#include "util.hpp"

class user_table{
    private:
        MYSQL *_mysql; //mysql操作句柄
        std::mutex _mutex;//互斥锁保护数据库的访问操作

    public:
        user_table(const std::string &host,
            const std::string &username,
            const std::string &password,
            const std::string &dbname,
            uint16_t port = 3306){

                _mysql = mysql_util::mysql_creat(host,username,password,dbname,port);
                assert(_mysql != NULL);
        };
        ~user_table(){

            mysql_util::mysql_destory(_mysql);
            _mysql = NULL;

        };
        bool insert(Json::Value &user){
            #define INSERT_USER "insert user values(0,'%s','%s',1000,0,0);"

            // Json::Value val;
            // bool ret = select_by_name(user["username"].asCString(),val);
            // if(ret == true)
            // {
            //     DLOG("user:%s存在",user["username"].asCString());
            //     return false;
            // }
            
           if(user["username"].isNull() || user["password"].isNull())
            {
                DLOG("请输入用户名和密码！");
                return false;
            }



            char sql[4096] = {0};
            sprintf(sql,INSERT_USER,user["username"].asCString(),user["password"].asCString());
            bool ret = mysql_util::mysql_exec(_mysql,sql);
            if(ret == false)
            {
                DLOG("插入用户失败");
                return false;
            }
            return true;


        };//注册时新增用户

        bool login(Json::Value &user){
            //用户名和密码作为查询过滤条件，查询到则一致，查询不到则错误
            #define LOGIN_USER "select id,score,total_count,win_count from user where username='%s' and password='%s';"
                char sql[4096] = {0};
                sprintf(sql,LOGIN_USER,user["username"].asCString(),user["password"].asCString());
                MYSQL_RES *res = NULL;
            {
                std::unique_lock<std::mutex> lock(_mutex);
                bool ret = mysql_util::mysql_exec(_mysql,sql);
            if(ret == false)
            {
                DLOG("用户登录失败");
                return false;
            }
            //若存在，只能存在一条数据
            res = mysql_store_result(_mysql);//数据保存在本地
            if(res == NULL)
            {
                DLOG("没有登录用户信息！");
                return false;
            }
            }
            int row_num = mysql_num_rows(res);
            if(row_num != 1)
            {
                DLOG("用户数据不唯一");
                return false;
            }

            MYSQL_ROW row = mysql_fetch_row(res);
            user["id"] = (Json::UInt64)std::stol(row[0]);
            user["score"] = (Json::UInt64)std::stol(row[1]);
            user["total_count"] = std::stoi(row[2]);
            user["win_count"] = std::stoi(row[3]);

            mysql_free_result(res);
            return true;
        
            

        };//登录验证,并返回详细信息
        bool select_by_name (const std::string &name,Json::Value &user){
            #define USER_BY_NAME "select id,score,total_count,win_count from user where username='%s';"
            char sql[4096] = {0};
                sprintf(sql,USER_BY_NAME,name.c_str());
                MYSQL_RES *res = NULL;
            {
                std::unique_lock<std::mutex> lock(_mutex);
            bool ret = mysql_util::mysql_exec(_mysql,sql);
            if(ret == false)
            {
                DLOG("获取用户名失败");
                return false;
            }
            //若存在，只能存在一条数据
            res = mysql_store_result(_mysql);//数据保存在本地
            if(res == NULL)
            {
                DLOG("没有用户信息！");
                return false;
            }
            }

            int row_num = mysql_num_rows(res);
            if(row_num != 1)
            {
                DLOG("用户数据不唯一");
                return false;
            }

            MYSQL_ROW row = mysql_fetch_row(res);
            user["id"] = (Json::UInt64)std::stol(row[0]);
            user["username"] = name;
            user["score"] = (Json::UInt64)std::stol(row[1]);
            user["total_count"] = std::stoi(row[2]);
            user["win_count"] = std::stoi(row[3]);

            mysql_free_result(res);
            return true;



        };//通过用户名获取用户信息
        bool select_by_id(uint64_t id,Json::Value &user){
        #define USER_BY_ID "select username,score,total_count,win_count from user where id='%d';"
            char sql[4096] = {0};
                sprintf(sql,USER_BY_ID,id);
                MYSQL_RES *res = NULL;
            {
                std::unique_lock<std::mutex> lock(_mutex);
            bool ret = mysql_util::mysql_exec(_mysql,sql);
            if(ret == false)
            {
                DLOG("获取用户id失败");
                return false;
            }
            //若存在，只能存在一条数据
            res = mysql_store_result(_mysql);//数据保存在本地
            if(res == NULL)
            {
                DLOG("没有用户信息！");
                return false;
            }
            }

            int row_num = mysql_num_rows(res);
            if(row_num != 1)
            {
                DLOG("用户数据不唯一");
                return false;
            }

            MYSQL_ROW row = mysql_fetch_row(res);
            user["id"] = (Json::UInt64)id;
            user["username"] = row[0];
            user["score"] = (Json::UInt64)std::stol(row[1]);
            user["total_count"] = std::stoi(row[2]);
            user["win_count"] = std::stoi(row[3]);

            mysql_free_result(res);
            return true;
        };//通过用户名获取用户信息

        bool win(uint64_t id){
            #define USER_WIN "update user set score=score+30,total_count=total_count+1,win_count=win_count+1 where id='%d';"
            char sql[4096] = {0};
            sprintf(sql,USER_WIN,id);
            bool ret = mysql_util::mysql_exec(_mysql,sql);
            if(ret == false)
            {
                DLOG("更新胜利用户信息失败");
                return false;
            }
            return true;

        };//胜利时天梯分数增加30，战斗场次增加1，胜利场次增加1
        bool lose(u_int64_t id){
            #define USER_LOSE "update user set score=score-30,total_count=total_count+1 where id='%d';"
            char sql[4096] = {0};
            sprintf(sql,USER_LOSE,id);
            bool ret = mysql_util::mysql_exec(_mysql,sql);
            if(ret == false)
            {
                DLOG("更新失败用户信息失败");
                return false;
            }
            return true;
        };//失败时天梯分数减少,30战斗场次增加1，其他不变



};
#endif